package com.cs.core.util;

import com.cs.core.common.VarConst;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @package com.cs.core.util
 * @class ZipUtil
 * @desc zip压缩
 * @author wind
 * @date    2023/9/21 11:17
 * @version v1.0
 */
public class ZipUtil {

    private ZipUtil(){

    }


    /**
     * 文件压缩
     * @param file
     * @param zipFile
     */
    public static void compress(String file, String zipFile){
        Path path = Paths.get(file);
        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFile)))) {
            if(Files.isDirectory(path)){
                // 压缩文件夹
                compressFolder(file, path.getFileName().toString(), zos);
            }else{
                addToZipFile(path.getFileName().toString(), path.toAbsolutePath().toString(), zos);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * zip文件夹压缩
     * @param sourceFolder 文件夹绝对路径
     * @param folderName
     * @param zipOutputStream 文件夹名称
     * @throws IOException
     */
    private static void compressFolder(String sourceFolder, String folderName, ZipOutputStream zipOutputStream) throws IOException {
        File folder = new File(sourceFolder);
        File[] files = folder.listFiles();

        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 压缩子文件夹
                    compressFolder(file.getAbsolutePath(), folderName + VarConst.FILE_SEPARATOR + file.getName(), zipOutputStream);
                } else {
                    // 压缩文件
                    addToZipFile(folderName + VarConst.FILE_SEPARATOR + file.getName(), file.getAbsolutePath(), zipOutputStream);
                }
            }
        }
    }

    private static void addToZipFile(String fileName, String filePath, ZipOutputStream zipOutputStream) throws IOException {
        // 创建ZipEntry对象并设置文件名
        ZipEntry entry = new ZipEntry(fileName);
        zipOutputStream.putNextEntry(entry);

        // 读取文件内容并写入Zip文件
        try (FileInputStream fileInputStream = new FileInputStream(filePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, bytesRead);
            }
        }
        // 完成当前文件的压缩
        zipOutputStream.closeEntry();
    }


}
